#include "SDL.h"
#include "SDL_opengl.h"
#include <vector>
#include <iostream>
#include <cmath>
#include <memory>

#include "Player.h"
#include "Map.h"
#include "Camera.h"
#include "Poly.h"

using namespace std;

//Uint32 ticks = 0;
const int TICKS_PER_SECOND = 50;
const int SKIP_TICKS = 1000 / TICKS_PER_SECOND;
const int MAX_FRAMESKIP = 10;

Uint32 next_game_tick = 0;

//Screen attributes
const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;
const int SCREEN_BPP = 32;

//Event handler
SDL_Event event;

// Map data and textures

auto_ptr<Map> map;
auto_ptr<Camera> camera;

Player* p;

bool init_GL()
{
	// Needed for SDL texture conversion
	glMatrixMode(GL_TEXTURE);
	glRotatef(180.0f,0.0f,0.0f,1.0f);
	glScalef(-1.0f,1.0f,1.0f);
 
	//back to normal
	glMatrixMode(GL_MODELVIEW);

    //Set clear color
    glClearColor( 0.4f, 0.2f, 0, 0 );

    //Initialize modelview matrix
    glMatrixMode( GL_MODELVIEW );
    glLoadIdentity();

    //If there was any errors
    if( glGetError() != GL_NO_ERROR )
    {
        return false;
    }

    //If everything initialized
    return true;
}

bool init()
{
    //Initialize SDL
    if( SDL_Init( SDL_INIT_EVERYTHING ) < 0 )
    {
        return false;
    }

    //Create Window
    if( SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_OPENGL ) == NULL )
    {
        return false;
    }

    //Initialize OpenGL
    if( init_GL() == false )
    {
        return false;
    }

    //Set caption
    SDL_WM_SetCaption( "OpenGL Test", NULL );

	// Load tile map
	map = auto_ptr<Map>(new Map("mars.tmap", 16, 12));

	// Create the player
	p = new Player(map.get());
	
	// Initialize the camera
	camera = auto_ptr<Camera>(new Camera(*p, *map));
	
    return true;
}

void update()
{
	//poly1->update( *poly2 );
	p->update();
	camera->update();

}

void display()
{
	//Clear the screen
	glClear( GL_COLOR_BUFFER_BIT );
	
	glEnable(GL_TEXTURE_2D);
	glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
	
	map->draw();
	
	p->draw();
	
	//Update screen
	SDL_GL_SwapBuffers();
}



int main( int argc, char *argv[] )
{

    //Quit flag
    bool quit = false;

    //Initialize
    if( init() == false )
    {
        return 1;
    }

	
	next_game_tick = SDL_GetTicks();

	//Wait for user exit
	while( quit == false )
	{

        //While there are events to handle
		while( SDL_PollEvent( &event ) )
		{
			//poly1->handleEvent( &event );
			p->handleEvent( &event );
			
			if( event.type == SDL_QUIT )
			{
                quit = true;
            }
		}

		for(int loops = 0; SDL_GetTicks() > next_game_tick && loops < MAX_FRAMESKIP; loops++)
		{
			update();
            
            next_game_tick += SKIP_TICKS;
            loops++;
		}
        
        display();
	}

	SDL_Quit();

	return 0;
}